#include <windows.h>
#include <boost/algorithm/string.hpp>
#include "../util/util.h"
#include "MenuBuilder.h"


UINT MenuBuilder::GetItemID(wstring key){
	return ID(key);
}
UINT MenuBuilder::ID(wstring key){
	return KeyID::GetID(key);
}

MenuBuilder::MenuBuilder(HMENU menu):menu_(menu){
}
MenuBuilder::MenuBuilder(const MenuBuilder& other){
	menu_ = other.menu_;
}
void MenuBuilder::Create(){
	menu_ = ::CreateMenu();
}
void MenuBuilder::CreateAsSub(){
	menu_ = ::CreateMenu();
}
void MenuBuilder::CreateAsPopup(){
	menu_ =::CreatePopupMenu();
}

HMENU MenuBuilder::GetMenu(){
	return menu_;
}
MenuBuilder::operator HMENU(){
	return GetMenu();
}
MenuBuilder& MenuBuilder::operator =(HMENU m){
	menu_ = m;
	return *this;
}
int MenuBuilder::GetItemCount(){
	return GetMenuItemCount(menu_);
}

void MenuBuilder::CheckItem(int index, bool check){
	MENUITEMINFO info = {0};
	info.cbSize = sizeof(MENUITEMINFO);
	info.fMask = MIIM_STATE;
	info.fState = check ? MFS_CHECKED :MFS_UNCHECKED;
	::SetMenuItemInfo(menu_, index, TRUE, &info);
}
void MenuBuilder::CheckItem(wstring key, bool check){
	MENUITEMINFO info = {0};
	info.cbSize = sizeof(MENUITEMINFO);
	info.fMask = MIIM_STATE;
	info.fState = check ? MFS_CHECKED :MFS_UNCHECKED;
	::SetMenuItemInfo(menu_, GetItemID(key), FALSE, &info);
}

void MenuBuilder::DeleteItem(wstring key){
	::DeleteMenu(menu_, GetItemID(key), MF_BYCOMMAND);
}
void MenuBuilder::DeleteItem(int  index){
	::DeleteMenu(menu_, index, MF_BYPOSITION);
}
BOOL MenuBuilder::AppendSubMenu(wstring text, HMENU subMenu){
	return InsertSubMenu(GetItemCount(), text, subMenu);
}
BOOL MenuBuilder::InsertSubMenu(int index, wstring text, HMENU subMenu){
	MENUITEMINFO info = {0};
	info.cbSize = sizeof(MENUITEMINFO);
	info.fMask = MIIM_SUBMENU | MIIM_STRING;
	info.hSubMenu = subMenu;
	info.dwTypeData = const_cast<wchar_t*>(text.c_str());
	info.cch = text.length();
	return InsertMenuItem(menu_, index, TRUE, &info);
}
HMENU MenuBuilder::GetSubMenu(wstring text){
	boost::to_lower(text);
	for(int i=0; i< GetItemCount(); ++i){
		HMENU m = GetSubMenu(i);
		wstring title = GetItemString(i);
		boost::to_lower(title);
		if(m  && text == title){
			return m;
		}
	}
	return 0;
}
bool MenuBuilder::IsSubMenu(int index){
	return GetSubMenu(index) ? true : false;
}
HMENU MenuBuilder::GetSubMenu(int index){
	MENUITEMINFO info = {0};
	info.cbSize = sizeof(MENUITEMINFO);
	info.fMask = MIIM_SUBMENU;
	if(::GetMenuItemInfo(menu_, index, TRUE, &info)){
		return info.hSubMenu;
	}
	return 0;
}
BOOL MenuBuilder::AppendSeprator(){
	return InsertSeprator(GetItemCount());
}
BOOL MenuBuilder::InsertSeprator(int index){
	MENUITEMINFO info = {0};
	info.cbSize = sizeof(MENUITEMINFO);
	info.fMask = MIIM_FTYPE ;
	info.fType = MFT_SEPARATOR;
	return ::InsertMenuItem(menu_, index, TRUE, &info);
}
BOOL MenuBuilder::InsertSeprator(wstring relKey){
	MENUITEMINFO info = {0};
	info.cbSize = sizeof(MENUITEMINFO);
	info.fMask = MIIM_FTYPE ;
	info.fType = MFT_SEPARATOR;
	return ::InsertMenuItem(menu_, GetItemID(relKey), FALSE, &info);
}

BOOL MenuBuilder::AppendItem(wstring key, wstring text){
	return InsertItem(GetItemCount(), key, text);
}
BOOL MenuBuilder::InsertItem(int index, wstring key, wstring text){
	MENUITEMINFO info = {0};
	info.cbSize = sizeof(MENUITEMINFO);
	info.fMask = MIIM_FTYPE |MIIM_STRING | MIIM_ID;
	info.fType = MFT_STRING;
	info.dwTypeData= const_cast<wchar_t*>(text.c_str());
	info.cch = text.length();
	info.wID = GetItemID(key);
	return ::InsertMenuItem(menu_, index, TRUE, &info);
}
BOOL MenuBuilder::InsertItem(wstring relKey, wstring key, wstring text){
	MENUITEMINFO info = {0};
	info.cbSize = sizeof(MENUITEMINFO);
	info.fMask = MIIM_FTYPE |MIIM_STRING | MIIM_ID;
	info.fType = MFT_STRING;
	info.dwTypeData= const_cast<wchar_t*>(text.c_str());
	info.cch = text.length();
	info.wID = GetItemID(key);
	return ::InsertMenuItem(menu_, GetItemID(relKey), FALSE, &info);
}
BOOL MenuBuilder::SetItemString(int index, wstring text){
	MENUITEMINFO info = {0};
	info.cbSize = sizeof(MENUITEMINFO);
	info.fMask = MIIM_FTYPE |MIIM_STRING;
	info.fType = MFT_STRING;
	info.dwTypeData= const_cast<wchar_t*>(text.c_str());
	info.cch = text.length();
	return ::SetMenuItemInfo(menu_, index, TRUE, &info);
}
BOOL MenuBuilder::SetItemString(wstring key, wstring text){
	MENUITEMINFO info = {0};
	info.cbSize = sizeof(MENUITEMINFO);
	info.fMask = MIIM_FTYPE |MIIM_STRING;
	info.fType = MFT_STRING;
	info.dwTypeData= const_cast<wchar_t*>(text.c_str());
	info.cch = text.length();
	return ::SetMenuItemInfo(menu_, GetItemID(key), FALSE, &info);
}
wstring MenuBuilder::GetItemString(int index){
	wchar_t buf[512] = {0};
	MENUITEMINFO info = {0};
	info.cbSize = sizeof(MENUITEMINFO);
	info.fMask = MIIM_FTYPE |MIIM_STRING;
	info.fType = MFT_STRING;
	info.dwTypeData= buf;
	info.cch = 511;
	::GetMenuItemInfo(menu_, index, TRUE, &info);
	return wstring(buf);
}
wstring MenuBuilder::GetItemString(wstring key){
	wchar_t buf[512] = {0};
	MENUITEMINFO info = {0};
	info.cbSize = sizeof(MENUITEMINFO);
	info.fMask = MIIM_FTYPE |MIIM_STRING;
	info.fType = MFT_STRING;
	info.dwTypeData= buf;
	info.cch = 511;
	::GetMenuItemInfo(menu_, GetItemID(key), FALSE, &info);
	return wstring(buf);
}
